﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Coding4Fun.Kinect.Wpf;
using Microsoft.Research.Kinect.Nui;

namespace Epitech.Krisk.Kinect.Cursor
{
    public class KinectCursor
    {
        private readonly List<Vector> _lastCursor = new List<Vector>();
        private DateTime _lastClick;
        private int _lastX;
        private int _lastY;
        private const int Threshold = 75;
        private int ScreenWidth;
        private int ScreenHeight;
        public event Action LetsClick;

        public enum CursorPrecision
        {
            High = 30,
            Normal = 10,
            Low = 1
        };

        private int _precision;
        private float _trust;

        public KinectCursor(CursorPrecision precision, float trust, int screenWidth, int screenHeight)
        {
            _lastX = 0;
            _precision = (int) precision;
            _trust = trust;
            ScreenHeight = screenHeight;
            ScreenWidth = screenWidth;
        }

        public void StartCursor(SkeletonData skeleton, JointID hand)
        {
            if (hand != JointID.HandRight && hand != JointID.HandLeft)
                throw new ArgumentException("Only hands can make the cursor moving");

            var scaledHand = skeleton.Joints[hand].ScaleTo(ScreenWidth, ScreenHeight, 0.3f, 0.2f);
            if (_lastCursor.Count == _precision)
                _lastCursor.RemoveAt(0);
            _lastCursor.Add(scaledHand.Position);

            if (_lastCursor.Count != _precision || skeleton.Joints[hand].Position.W < _trust)
                return;
            var xCoordinate = (int) scaledHand.Position.X;
            var yCoordinate = (int) scaledHand.Position.Y;

            if (_lastY == 0)
            {
                _lastX = xCoordinate;
                _lastY = yCoordinate;
            }
            if (Math.Abs(_lastX - xCoordinate) < Threshold && Math.Abs(_lastY - yCoordinate) < Threshold)
            {
                if (Math.Abs(_lastClick.Subtract(DateTime.Now).TotalSeconds) > 1)
                {
                    LetsClick();
                    MouseHook.SendClick();
                    _lastClick = DateTime.Now;
                    _lastX = xCoordinate;
                    _lastY = yCoordinate;
                }
            }
            else
            {
                _lastClick = DateTime.Now;
                _lastX = xCoordinate;
                _lastY = yCoordinate;

            }
            double x = _lastCursor.Average(j => j.X);
            double y = _lastCursor.Average(j => j.Y);
            MouseHook.MoveMouse(new System.Drawing.Point((int) Math.Round(x), (int) Math.Round(y)));
        }

    }
}
